package examples1;

import net.corda.core.contracts.Command;
import net.corda.core.contracts.CommandData;
import net.corda.core.transactions.LedgerTransaction;

import java.security.PublicKey;
import java.util.List;

/* Our contract, governing how our state will evolve over time.
 * See src/main/java/examples/ArtContract.java for an example. */
public class IouContract {

    public static String ID = "examples1.IouContract";  //基于安全问题，id必须是某个包下的类，而不是IouContract.class

    /**
     * 具体的合约内容，需要对transaction的合法性进行验证
     * @param tx
     * @throws IllegalArgumentException
     */
    public void verify(LedgerTransaction tx) throws IllegalArgumentException {
        if(tx.getCommands().size()!=0){
            throw new IllegalArgumentException("Transaction must have one command! ");
        }
        Command command  = tx.getCommand(0);
        if(command.getValue() instanceof  Commands.Issue){
            //shape（state和command的输入和输出限制）
            if(tx.getInputStates().size()!=0){
                throw new IllegalArgumentException("Issue must have zero input !");
            }if(tx.getOutputStates().size()!=1){
                throw new IllegalArgumentException("Issue must have one output ! ");
            }
            //Content（具体的业务逻辑）
            if(!(tx.getOutput(0) instanceof IouState)){
                throw new IllegalArgumentException("Output state must be a IouState !");
            }
            IouState iouState = (IouState)tx.getOutput(0);
            if(iouState.getAmount()<= 0){
                throw new IllegalArgumentException("Amount must be a positive number !");
            }
            //signer（签名）
            List<PublicKey> requiredSigner = command.getSigners();
            PublicKey issuerKey = iouState.getIssur().getOwningKey();
            if(!(requiredSigner.contains(issuerKey))){
                throw new IllegalArgumentException("Issuer must a required signer !");
            }
        }else{
            throw new IllegalArgumentException("Unrecognized command !");
        }
    }

    /**
     * 定义不同类型的命令
     */
    public interface Commands extends CommandData {
        class Issue implements Commands { }
    }
}
